<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue在线代码编辑器</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.3.4/vue.global.prod.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" rel="stylesheet" />
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    body {
      font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
      background: #1a1a1a;
      color: #fff;
      height: 100vh;
      overflow: hidden;
    }

    .editor-container {
      display: flex;
      flex-direction: column;
      height: 100vh;
    }

    .header {
      background: #2d2d2d;
      padding: 15px 20px;
      border-bottom: 1px solid #444;
      display: flex;
      align-items: center;
      gap: 20px;
    }

    .header h1 {
      font-size: 20px;
      font-weight: 600;
      color: #fff;
    }

    .language-selector {
      display: flex;
      align-items: center;
      gap: 10px;
    }

    .language-selector label {
      color: #ccc;
      font-size: 14px;
    }

    .language-selector select {
      background: #3d3d3d;
      border: 1px solid #555;
      border-radius: 6px;
      padding: 8px 12px;
      color: #fff;
      font-size: 14px;
      cursor: pointer;
      outline: none;
      transition: border-color 0.2s;
    }

    .language-selector select:hover {
      border-color: #007acc;
    }

    .editor-wrapper {
      flex: 1;
      display: flex;
      position: relative;
      background: #1e1e1e;
    }

    .line-numbers {
      background: #252526;
      color: #858585;
      padding: 20px 8px 20px 15px;
      font-size: 14px;
      line-height: 1.5;
      text-align: right;
      user-select: none;
      min-width: 50px;
      border-right: 1px solid #3e3e42;
    }

    .editor-content {
      flex: 1;
      position: relative;
      overflow: auto;
    }

    .code-input {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: transparent;
      border: none;
      outline: none;
      resize: none;
      font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
      font-size: 14px;
      line-height: 1.5;
      padding: 20px 15px;
      color: #d4d4d4;
      z-index: 2;
      caret-color: #fff;
    }

    .code-highlight {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      pointer-events: none;
      z-index: 1;
      overflow: hidden;
    }

    .code-highlight pre {
      margin: 0;
      padding: 20px 15px;
      background: transparent !important;
      font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
      font-size: 14px;
      line-height: 1.5;
      white-space: pre-wrap;
      word-wrap: break-word;
    }

    /* 自定义滚动条 */
    ::-webkit-scrollbar {
      width: 12px;
      height: 12px;
    }

    ::-webkit-scrollbar-track {
      background: #1e1e1e;
    }

    ::-webkit-scrollbar-thumb {
      background: #424242;
      border-radius: 6px;
    }

    ::-webkit-scrollbar-thumb:hover {
      background: #4f4f4f;
    }

    /* 代码高亮主题覆盖 */
    .token.comment,
    .token.prolog,
    .token.doctype,
    .token.cdata {
      color: #6a9955;
    }

    .token.punctuation {
      color: #d4d4d4;
    }

    .token.property,
    .token.tag,
    .token.boolean,
    .token.number,
    .token.constant,
    .token.symbol,
    .token.deleted {
      color: #b5cea8;
    }

    .token.selector,
    .token.attr-name,
    .token.string,
    .token.char,
    .token.builtin,
    .token.inserted {
      color: #ce9178;
    }

    .token.operator,
    .token.entity,
    .token.url,
    .language-css .token.string,
    .style .token.string {
      color: #d4d4d4;
    }

    .token.atrule,
    .token.attr-value,
    .token.keyword {
      color: #569cd6;
    }

    .token.function,
    .token.class-name {
      color: #dcdcaa;
    }

    .token.regex,
    .token.important,
    .token.variable {
      color: #d16969;
    }

    /* 响应式设计 */
    @media (max-width: 768px) {
      .header {
        padding: 10px 15px;
        flex-direction: column;
        gap: 10px;
        align-items: flex-start;
      }

      .header h1 {
        font-size: 18px;
      }

      .line-numbers {
        min-width: 40px;
        padding: 15px 6px 15px 10px;
        font-size: 13px;
      }

      .code-input,
      .code-highlight pre {
        font-size: 13px;
        padding: 15px 10px;
      }
    }
  </style>

</head>
<body>
<div id="app">
  <div class="editor-container">
    <div class="header">
      <h1>🚀 在线代码编辑器</h1>
      <div class="language-selector">
        <label for="language">语言:</label>
        <select id="language" v-model="selectedLanguage" @change="updateHighlighting">
          <option v-for="lang in languages" :key="lang.value" :value="lang.value">
            {{ lang.name }}
          </option>
        </select>
      </div>
    </div>
    <div class="editor-wrapper">
      <div class="line-numbers">
        <div v-for="(line, index) in lineNumbers" :key="index">
          {{ index + 1 }}
        </div>
      </div>

      <div class="editor-content">
                <textarea
                        class="code-input"
                        v-model="code"
                        @input="updateCode"
                        @scroll="syncScroll"
                        ref="textarea"
                        :placeholder="placeholder"
                        spellcheck="false"
                ></textarea>

        <div class="code-highlight" ref="highlight">
          <pre><code :class="`language-${selectedLanguage}`" v-html="highlightedCode"></code></pre>
        </div>
      </div>
    </div>
  </div>
</div>

<script>
  const { createApp, ref, computed, nextTick, onMounted } = Vue;

  createApp({
    setup() {
      const code = ref('');
      const selectedLanguage = ref('javascript');
      const textarea = ref(null);
      const highlight = ref(null);

      const languages = [
        { value: 'javascript', name: 'JavaScript' },
        { value: 'typescript', name: 'TypeScript' },
        { value: 'python', name: 'Python' },
        { value: 'java', name: 'Java' },
        { value: 'cpp', name: 'C++' },
        { value: 'c', name: 'C' },
        { value: 'csharp', name: 'C#' },
        { value: 'php', name: 'PHP' },
        { value: 'ruby', name: 'Ruby' },
        { value: 'go', name: 'Go' },
        { value: 'rust', name: 'Rust' },
        { value: 'kotlin', name: 'Kotlin' },
        { value: 'swift', name: 'Swift' },
        { value: 'html', name: 'HTML' },
        { value: 'css', name: 'CSS' },
        { value: 'scss', name: 'SCSS' },
        { value: 'json', name: 'JSON' },
        { value: 'xml', name: 'XML' },
        { value: 'sql', name: 'SQL' },
        { value: 'bash', name: 'Bash' },
        { value: 'powershell', name: 'PowerShell' },
        { value: 'yaml', name: 'YAML' },
        { value: 'markdown', name: 'Markdown' },
        { value: 'vue', name: 'Vue' },
        { value: 'jsx', name: 'JSX' },
        { value: 'tsx', name: 'TSX' }
      ];

      const defaultCode = {
        javascript: `// 欢迎使用在线代码编辑器

function greet(name) {
console.log(`Hello, ${name}!`);
}
greet('World');
// 试试其他语言！,                     python: # 欢迎使用在线代码编辑器
def greet(name):
print(f"Hello, {name}!")
greet("World")
试试其他语言！`,
              html: `<!DOCTYPE html>

<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World</title>
</head>
<body>
<h1>欢迎使用在线代码编辑器</h1>
<p>试试其他语言！</p>
</body>
</html>,                     css: /* 欢迎使用在线代码编辑器 */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.title {
color: #333;
font-size: 2rem;
margin-bottom: 1rem;
}
/* 试试其他语言！ */,                     json: {
"name": "在线代码编辑器",
"version": "1.0.0",
"description": "一个功能强大的在线代码编辑器",
"features": [
"语法高亮",
"行号显示",
"多语言支持"
],
"message": "试试其他语言！"
}`
    };
      const lineNumbers = computed(() => {
        return code.value.split('\n');
      });

      const highlightedCode = ref('');

      const placeholder = computed(() => {
        return `请输入${languages.find(l => l.value === selectedLanguage.value)?.name}代码...`;
      });

      const updateHighlighting = () => {
        if (code.value.trim() === '') {
          code.value = defaultCode[selectedLanguage.value] || '// 开始编写代码...';
        }

        nextTick(() => {
          if (window.Prism) {
            const highlighted = Prism.highlight(
                    code.value,
                    Prism.languages[selectedLanguage.value] || Prism.languages.javascript,
                    selectedLanguage.value
            );
            highlightedCode.value = highlighted;
          }
        });
      };

      const updateCode = () => {
        updateHighlighting();
      };

      const syncScroll = () => {
        if (textarea.value && highlight.value) {
          highlight.value.scrollTop = textarea.value.scrollTop;
          highlight.value.scrollLeft = textarea.value.scrollLeft;
        }
      };

      onMounted(() => {
        // 设置初始代码
        code.value = defaultCode[selectedLanguage.value];
        updateHighlighting();

        // 配置 Prism 自动加载器
        if (window.Prism && window.Prism.plugins && window.Prism.plugins.autoloader) {
          window.Prism.plugins.autoloader.languages_path = 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/';
        }
      });

      return {
        code,
        selectedLanguage,
        languages,
        lineNumbers,
        highlightedCode,
        placeholder,
        textarea,
        highlight,
        updateCode,
        updateHighlighting,
        syncScroll
      };
    }
  }).mount('#app');
</script>

</body>
</html>